﻿#include "MeasureView/MeasureLine.h"
#include "MeasureView/MeasureDataSet.h"
#include <QGuiApplication>
#include <QDebug>
namespace Qly {

double MeasureLine::barLength_inter_pix = 1000;
double MeasureLine::barLength_final_pix = 20;
MeasureLine::MeasureLine(MeasureDataSet *parent)
    :MeasureElement(parent)
{
    m_measureType = Line;
    m_results_pix.resize(3); // 点到点距离测量有3个结果。第一个是长度，第二个是X方向距离，第三个是Y方向距离。
    m_results_um.resize(3);
    m_keyPoints_um.resize(2);
    m_keyPoints_pix.resize(2);
    m_textTemplate = parent->m_textTemplate_MeasureLine;
}

bool MeasureLine::testMoveState(QPointF point_pix)
{
//    qDebug() << "in testMoveState";
    if(m_measureState != DS_FINISH)
        return false;

    QPointF p = m_keyPoints_pix[0] - point_pix;

//    qDebug() << "m_keyPoints_pix[0] = " << m_keyPoints_pix[0];
//    qDebug() << "m_keyPoints_pix[1] = " << m_keyPoints_pix[1];
//    qDebug() << "point = " << point_pix;
    if(p.manhattanLength() < 10)
    {
        m_adjust = 1;
        m_tempPoint_pix = point_pix;
        return true;
    }
    p = m_keyPoints_pix[1] - point_pix;
    if(p.manhattanLength() < 10)
    {
        m_adjust = 2;
        m_tempPoint_pix = point_pix;
        return true;
    }
    return false;
}

void MeasureLine::setStartPoint(QPointF point_pix, QPointF point_um)
{
    m_keyPoints_pix[0] = point_pix;
    m_keyPoints_pix[1] = point_pix;
    m_keyPoints_um[0] = point_um;
    m_keyPoints_um[1] = point_um;

    compute();
    updateText(true);
    m_measureState = DS_STATE1;
}

void MeasureLine::setTempEndPoint(QPointF point_pix, QPointF point_um)
{
    m_keyPoints_pix[1] = point_pix;
    m_keyPoints_um[1] = point_um;
    compute();
    updateText(true);
}

void MeasureLine::setEndPoint(QPointF point_pix, QPointF point_um)
{
    m_keyPoints_pix[1] = point_pix;
    m_keyPoints_um[1] = point_um;
    compute();
    updateText(true);
    m_measureState = DS_FINISH;
}

void MeasureLine::compute()
{
    //qDebug() << "MeasureLine::compute()";
    m_results_pix[1] = m_keyPoints_pix[1].x() - m_keyPoints_pix[0].x();
    m_results_pix[2] = m_keyPoints_pix[1].y() - m_keyPoints_pix[0].y();
    m_results_pix[0] = hypot( m_results_pix[1], m_results_pix[2] );

    double ps = m_pParent->m_pixSize_um;
    m_results_um[0] = ps * m_results_pix[0];
    m_results_um[1] = ps * m_results_pix[1];
    m_results_um[2] = ps * m_results_pix[2];

    buildBar();
}

void MeasureLine::buildBar()
{
    if( m_keyPoints_pix[1].x() == m_keyPoints_pix[0].x() ) // 也包括了  m_results_pix[0] == 0 的情况，下面就不需要特殊处理了
    {
        m_cos_theta = 0.0;
        m_sin_theta  = 1.0;
    }
    else
    {
        m_cos_theta = ( m_keyPoints_pix[1].x() - m_keyPoints_pix[0].x() ) / m_results_pix[0];
        m_sin_theta = ( m_keyPoints_pix[1].y() - m_keyPoints_pix[0].y() ) / m_results_pix[0];
    }

    double cos_theta = - m_sin_theta; // 与主直线垂直
    double sin_theta = m_cos_theta;

    double barlen = (m_measureState == DS_FINISH) ? barLength_final_pix : barLength_inter_pix;

    m_line1_start.setX( m_keyPoints_pix[0].x() - barlen / 2 * cos_theta );
    m_line1_start.setY( m_keyPoints_pix[0].y() - barlen / 2 * sin_theta );

    m_line1_end.setX( m_keyPoints_pix[0].x() + barlen / 2 * cos_theta );
    m_line1_end.setY( m_keyPoints_pix[0].y() + barlen / 2 * sin_theta );

    m_line2_start.setX( m_keyPoints_pix[1].x() - barlen / 2 * cos_theta );
    m_line2_start.setY( m_keyPoints_pix[1].y() - barlen / 2 * sin_theta );

    m_line2_end.setX( m_keyPoints_pix[1].x() + barlen / 2 * cos_theta );
    m_line2_end.setY( m_keyPoints_pix[1].y() + barlen / 2 * sin_theta );
}

void MeasureLine::updateText(bool updatePosition)
{
    Q_UNUSED(updatePosition);
    QString text = m_textTemplate;
//    qDebug() << m_results_um[0]<< m_textTemplate;

    m_pParent->m_unitConvert_MeasureLine.replaceLength(text, m_results_um[1], "@lengthX", "@unitX");
    m_pParent->m_unitConvert_MeasureLine.replaceLength(text, m_results_um[2], "@lengthY", "@unitY");
    m_pParent->m_unitConvert_MeasureLine.replaceLength(text, m_results_um[0], "@length", "@unit");

    QString valueStr = QString::number(m_id);
    text.replace("@id", valueStr, Qt::CaseSensitive);

    if( !updatePosition )
    {
        QPointF pix, um;
        m_textBlock.anchorPoint(pix, um);
        m_textBlock.setText(text);
        m_textBlock.moveTo(pix, um);
    }
    else
    {
        QPointF p_pix = (m_keyPoints_pix[0] + m_keyPoints_pix[1]) / 2 ;
        QPointF p_um = (m_keyPoints_um[0] + m_keyPoints_um[1]) / 2;
        m_textBlock.setText(text);
        m_textBlock.moveTo(p_pix, p_um);
    }
}

bool MeasureLine::adjust(QPointF offset_pix, QPointF offset_um)
{
    if(m_measureState != DS_FINISH)
        return false;
    if(m_adjust == 1) // 调整起点坐标
    {
        m_keyPoints_pix[0] += offset_pix;
        m_keyPoints_um[0] += offset_um;
        compute();
        updateText();
        return true;
    }
    else if(m_adjust == 2)
    {
        m_keyPoints_pix[1] += offset_pix;
        m_keyPoints_um[1] += offset_um;
        compute();
        updateText();
        return true;
    }
    return false;
}

int MeasureLine::mouseLButtonPress(QPointF point_pix, QPointF point_um)
{
    if( m_measureState == DS_IDLE )
    {
        //qDebug() << "MeasureLine::mouseLButtonPress, m_measureState == DS_IDLE";
        //setStartPoint(point_pix, point_um);
        m_keyPoints_pix[0] = point_pix;
        m_keyPoints_pix[1] = point_pix;
        m_keyPoints_um[0] = point_um;
        m_keyPoints_um[1] = point_um;
        compute();
        updateText(true);
        m_measureState = DS_STATE1;
        return m_measureState;
    }
    if( m_measureState == DS_STATE1 )
    {
        bool isCtrlPressed = QGuiApplication::keyboardModifiers() & Qt::ControlModifier;
        //qDebug() << "MeasureLine::mouseLButtonPress, m_measureState == DS_STATE1";
        if(isCtrlPressed)
        {
            QPointF tmp_pix, tmp_um;
            if(abs(point_pix.x() - m_keyPoints_pix[0].x()) > abs(point_pix.y() - m_keyPoints_pix[0].y()))
            {
                tmp_pix.setX(point_pix.x());
                tmp_pix.setY(m_keyPoints_pix[0].y());

                tmp_um.setX(point_um.x());
                tmp_um.setY(m_keyPoints_um[0].y());
            }
            else
            {
                tmp_pix.setX(m_keyPoints_pix[0].x());
                tmp_pix.setY(point_pix.y());

                tmp_um.setX(m_keyPoints_um[0].x());
                tmp_um.setY(point_um.y());
            }
            setEndPoint(tmp_pix, tmp_um);
        }
        else
        {
            setEndPoint(point_pix, point_um);

        }
        if( m_keyPoints_pix[0] == m_keyPoints_pix[1] )
        {
            m_measureState = DS_ERROR;
        }
        else
        {
            compute();
            updateText(true);
        }
    }
    return m_measureState;
}

int MeasureLine::mouseMove(QPointF point_pix, QPointF point_um)
{
    if( m_measureState == DS_STATE1 )
    {
        bool isCtrlPressed = QGuiApplication::keyboardModifiers() & Qt::ControlModifier;
        if(isCtrlPressed)
        {
            QPointF tmp_pix, tmp_um;
            if(abs(point_pix.x() - m_keyPoints_pix[0].x()) > abs(point_pix.y() - m_keyPoints_pix[0].y()))
            {
                tmp_pix.setX(point_pix.x());
                tmp_pix.setY(m_keyPoints_pix[0].y());

                tmp_um.setX(point_um.x());
                tmp_um.setY(m_keyPoints_um[0].y());
            }
            else
            {
                tmp_pix.setX(m_keyPoints_pix[0].x());
                tmp_pix.setY(point_pix.y());

                tmp_um.setX(m_keyPoints_um[0].x());
                tmp_um.setY(point_um.y());
            }
            setTempEndPoint(tmp_pix, tmp_um);
        }
        else
        {
            setTempEndPoint(point_pix, point_um);
        }
        //qDebug() << "MeasureLine::mouseMove, m_measureState == DS_STATE1";
        return 1;
    }
    return 0;
}

void MeasureLine::paint(QPainter &painter)
{
    if( m_measureState != DS_IDLE )
    {
        painter.save();
        painter.setPen(m_pen);
        painter.drawLine ( m_keyPoints_pix[0], m_keyPoints_pix[1] );
        painter.drawLine ( m_line1_start, m_line1_end );
        painter.drawLine ( m_line2_start, m_line2_end );

        if(m_measureState != MeasureElement::DS_ERROR)
        {
            m_textBlock.draw(painter);

            if(m_textMoving)
            {
                QPen pen = m_pen;
                pen.setStyle(Qt::DashDotLine);
                painter.setPen(pen);
                QPointF p = m_textBlock.anchorPoint();
                painter.drawLine(p, (m_keyPoints_pix[0] + m_keyPoints_pix[1]) / 2.0);
                painter.setPen(m_pen);
            }
        }

        painter.restore();
    }
}

}
